const express = require('express')
const app = express()
// 设置端口
const PORT = 3000
// 解决跨域配置可访问的主机，*代表所有主机
const HOST = '*'

// 下面是关于session持久化存储的内容
// 引入express-session模块
const session = require('express-session')
// 引入connect-mongo模块，为session做持久化存储
const MongoStore = require('connect-mongo')(session)

// 引入 body-parser 中间件
const bodyParser = require('body-parser');
//解析application/json
app.use(bodyParser.json({ extended: true }));
//解析application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: true }));

// 引入path模块
const path = require('path')

const store = session({
    name: 'userId', // 设置cookie的name，默认值是：connect.sid
    secret: 'huangyanwu', // 参与加密的字符串（又叫签名）
    saveUninitialized: false, // 是否在存储内容之前创建会话
    resave: true, // 是否在每次请求时，强制重新保存session，即使他们没有变化
    store: new MongoStore({
        url: 'mongodb://localhost:27017/session_container',
        touchAfter: 2 * 3600 //每两个小时存储一次
    }),
    cookie: {
        httpOnly: true,
        maxAge: 1000 * 60 * 3 // cookie过期时间
    }
})
app.use(store)

// 解决跨域
const cors = require('cors');
app.use(cors());


// 引入jwt验证模块
const {verifyToken} = require('./utils/verification')
// 后台管理引入验证
const rolesPermission = require('./utils/validateRole/rolesPermission')

// 后台管理的处理,白名单内的路由不需要进行权限验证
const whitePath = [
    '/favicon.ico',
    '/login',
    '/upload/registerFile',
    '/user/register',
    '/logout',
    '/test'
]

app.all('*',function (req, res, next) {
    if (req.method == 'OPTIONS') {
        res.send('200');
    } else {
        let token = req.get('permission')? req.headers['permission'] : ''
        if(whitePath.indexOf(req.path) != -1 || req.get('Accept') == 'image/avif,image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8'){
            next();
        }else {
            let verifyResult = verifyToken(token)
            // 当请求头没有permission ,或者对token验证失败时，返回403让用户重新登录
            if( token == '' || !verifyResult.bol ){
                let data = {
                    code: '403',
                    msg: '登录信息过期，请重新登陆！'
                }
                res.json(data)
            }else {  // 验证token成功后，进入要访问的路由
                if (req.get('Referer') == 'http://localhost:9000/' || req.get('backEnd') == 'backEndManager'){
                    // 后台管理一定要先验证角色权限的，因为在端口9000下运行的，这个是不变的，再不济所有路由的请求头在后台管理的前端页面都携带一个标记
                    const validate = {
                        permitRoles: ['admin','boss','manager','server'],
                        secret: req.get('permission')
                    }

                    const data = {
                        code: '200',
                        data: 'error',
                        msg: '权限不足'
                    }
                    //当前路由只能有后台权限的人员进入
                    if(!rolesPermission(validate)) return res.json(data)
                    next()
                }else{
                    next()
                }
            }
        }

    }
});

// 暴露所有静态资源
app.use(express.static('public'))

// 不做计费的文件夹是free，计费的文件夹是charing（广告的图片都是要做一层计费的）
app.get('/public/free/*', function (req, res) {
    res.sendFile( path.resolve(__dirname + req.path) );
})

// 引入轮播图计费模块
const rotationCharge = require('./routes/adminRoutes/rotation/charg')
app.use(rotationCharge);

// 引入登陆路由
const loginRouter = require('./routes/login/login')
app.use(loginRouter)
// 引入退出登录的路由
const logoutRouter = require('./routes/login/logout')
app.use(logoutRouter)

// 引入用户信息路由
const userInfo = require('./routes/users/userInfo')
// 引入修改密码路由
const changePassword = require('./routes/users/changePassword')
// 引入修改个人信息路由
const changeInformation = require('./routes/users/changeInformation')
// 注册
const register = require('./routes/register')
// 保存user的路由
const userRoutes = [
    userInfo,
    changePassword,
    changeInformation,
    register
]
app.use('/user',
    userRoutes
)

// 引入上传路由
const upload = require('./routes/upload/upload')
app.use('/upload',bodyParser.json({limit: '2mb'}),upload)
// 引入删除文件路由
const removeFile = require('./routes/remove/removeFile')
app.use(removeFile)

// 引入增加地址的路由
const addAddress = require('./routes/address/addAddress')
// 引入查询地址信息的路由
const showAddress = require('./routes/address/showAddress')
// 引入修改地址的路由
const updateAndDeleteAddress = require('./routes/address/updateAndDeleteAddress')
// 保存与地址相关的路由
const adress = [
    addAddress,
    showAddress,
    updateAndDeleteAddress
]
app.use('/address',adress)

const faceRotation = require('./routes/rotation/showRotation')
app.use(faceRotation)

const faceShowGoods = require('./routes/goods/showGoods')
app.use(faceShowGoods)




// 后台管理系统路由
// 引入增加与查看分类路由
const addAndShowClassification = require('./routes/adminRoutes/classification/addAndShow')
// 引入修改分类的路由
const updateAndDeleteClassification = require('./routes/adminRoutes/classification/updateAndDelete')
const classification = [
    addAndShowClassification,
    updateAndDeleteClassification
]
app.use('/classification',classification)

// 引入轮播图管理路由
const addAndUpdateRotation = require('./routes/adminRoutes/rotation/addAndUpdate')
const showEndRotation = require('./routes/adminRoutes/rotation/show')
// 直通车（轮播图）管理
const managerRotation = [
    addAndUpdateRotation,
    showEndRotation
]
app.use('/managerRotation',managerRotation)

// 引入商品管理的增删改查
const addGoods = require('./routes/adminRoutes/managerGoods/add')
const updateGoods = require('./routes/adminRoutes/managerGoods/update')
const showGoods = require('./routes/adminRoutes/managerGoods/show')
// 商品管理
const managerGoods = [
    addGoods,
    updateGoods,
    showGoods
]
app.use('/managerGoods',managerGoods)

// 引入测试路由
// const testRouter = require('./routes/test')
// app.use(testRouter)

// 引入401路由,无权限路由
// const noPermission = require('./routes/401')
// app.use(noPermission)

// 引入404路由,404路由一定要放在所有路由的最后面
const notFound = require('./routes/404')
app.use(notFound)

app.listen(PORT,(err)=>{
    if (err){
        console.log(err)
    }
})

